package com.liuchuanzheng.lcz_wanandroid.net.base

import android.util.Log
import com.liuchuanzheng.lcz_wanandroid.App
import com.liuchuanzheng.lcz_wanandroid.BuildConfig
import com.liuchuanzheng.lcz_wanandroid.util.GenericSuperclassUtil
import okhttp3.Cache
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.util.concurrent.TimeUnit
import com.liuchuanzheng.lcz_wanandroid.net.cookie.PersistentCookieJar
import com.liuchuanzheng.lcz_wanandroid.net.cookie.cache.SetCookieCache
import com.liuchuanzheng.lcz_wanandroid.net.cookie.persistence.SharedPrefsCookiePersistor
import okhttp3.logging.HttpLoggingInterceptor


/**
 * @author 刘传政
 * @date 2021/5/25 14:04
 * QQ:1052374416
 * 电话:18501231486
 * 作用:
 * 注意事项:
 */
abstract class RetrofitManager<API> {
    private val CONNECT_TIMEOUT = 10L
    private val READ_TIMEOUT = 10L
    private val WRITE_TIMEOUT = 10L
    private val cookieJar by lazy {
        PersistentCookieJar(SetCookieCache(), SharedPrefsCookiePersistor(App.instance))
    }
    /**log**/
    private val logger = HttpLoggingInterceptor.Logger {
        //如何打印网络数据。自定义
        Log.i(this::class.simpleName, it)
    }
    private val logInterceptor = HttpLoggingInterceptor(logger).apply {
        if (BuildConfig.DEBUG) {
            level = HttpLoggingInterceptor.Level.BODY
        } else {
            level = HttpLoggingInterceptor.Level.BASIC
        }
    }
    var apiService: API
        get() {
            return field
        }
        private set

    init {
        val cache = Cache(
            File(App.instance.applicationContext.cacheDir, "HttpCache"), 1024 * 1024 * 100
        )
        var mOkHttpClient: OkHttpClient

        var builder = OkHttpClient.Builder()
            .cache(cache)
            .cookieJar(cookieJar)
            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)
            .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)
            .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)
            .addInterceptor(DoSomethingInterceptor()) //添加一个统一处理某些事的拦截器
        if (getAppInterceptor() != null) {
            builder.addInterceptor(getAppInterceptor()!!)
        }
        builder
            .addNetworkInterceptor(LoggingInterceptor()) //添加自定义log拦截器 addNetworkInterceptor能打印cookies等信息，addInterceptor不能打印cookies
//            .addNetworkInterceptor (logInterceptor)//官方的log拦截器 看着格式有点乱
            .retryOnConnectionFailure(true)//失败重连
        mOkHttpClient = builder.build()
        var retrofit: Retrofit = Retrofit.Builder()
            .baseUrl(getBaseUrl())
            .client(mOkHttpClient)
            .addConverterFactory(GsonConverterFactory.create()) // 添加Gson转换器
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 添加Rx适配器
            .build()
        apiService = retrofit.create(getEntityClass()) as API
    }

    /**
     * 设置app自己的拦截器,添加一些请求头,处理token失效等
     */
    abstract fun getAppInterceptor(): Interceptor?

    /**
     * 一个网络管理类只有一个baseurl,如果有多个baseurl的项目,就创建多个此类的实现
     */
    abstract fun getBaseUrl(): String

    private fun getEntityClass(): Class<*>? {
        return GenericSuperclassUtil.getActualTypeArgument(this.javaClass, 0)
    }
    /**清除Cookie*/
    fun clearCookie() = cookieJar.clear()
}